//
//  blockprtyAppDelegate.m
//  blockprty
//
//  Created by Sean O' Shea on 7/16/11.
//  Copyright 2011 Eye-Fi INC. All rights reserved.
//

#import "blockprtyAppDelegate.h"
#import <Rdio/Rdio.h>
#import "ASIHTTPRequest.h"
#import "BlockPrtyMainView.h"

@interface blockprtyAppDelegate (interface)
- (void) apiCall:(NSString*)method args:(NSDictionary*)args successBlock:(SuccessBlock)successBlock failureBlock:(FailureBlock)failureBlock;
- (void) apiCall:(NSString*)method args:(NSDictionary*)args queryBlock:(QueryBlock)successBlock failureBlock:(FailureBlock)failureBlock;	

@end

@implementation blockprtyAppDelegate

@synthesize facebook;
@synthesize window;


#pragma mark -
#pragma mark Application lifecycle

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
    // Override point for customization after application launch.
    
    [self.window makeKeyAndVisible];
    
	// queue for ASI network stuff, making API calls to the blockprty service
	queue = dispatch_queue_create("blockprty.serial", NULL);
	
	mainViewController = [[BlockPrtyMainView alloc] initWithNibName:@"BlockPrtyMainView"
															 bundle:nil];
	[window addSubview:[mainViewController view]];
	
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
	
    return [facebook handleOpenURL:url]; 
}

- (void)fbDidLogin {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:[facebook accessToken] forKey:@"FBAccessTokenKey"];
    [defaults setObject:[facebook expirationDate] forKey:@"FBExpirationDateKey"];
    [defaults synchronize];
		
	[self addCheckin];
}


- (void)applicationWillResignActive:(UIApplication *)application {
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
     */
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    /*
     Called as part of  transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
     */
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
}


- (void)applicationWillTerminate:(UIApplication *)application {
    /*
     Called when the application is about to terminate.
     See also applicationDidEnterBackground:.
     */
}


#pragma mark -
#pragma mark Memory management

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    /*
     Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
     */
}

- (void) checkin {	
	SuccessBlock successBlock = ^(NSString *result) {

	};
	FailureBlock failureBlock = ^(NSString *err) {

	};
	NSDictionary *args = [[NSDictionary alloc] initWithObjectsAndKeys:
						   @"email", @"email",
						   @"lat", @"lat",
						   @"lng", @"lng",
						   @"taste", @"tasteSig",
						   nil];
	[self apiCall:@"checkin"
			 args:args
		successBlock:successBlock
		failureBlock:failureBlock];
}

- (void)submitTasteForLatitude:(float)latitude longitude:(float)longitude artistString:(NSString *)artistList user:(NSString *)user
{
	SuccessBlock successBlock = ^(NSString *result) {
		NSLog(@"success block for add check result is %@", result);
	};
	FailureBlock failureBlock = ^(NSString *err) {
		NSLog(@"failure block for add check result is %@", err);
	};
	
	NSDictionary *args = [[NSDictionary alloc] initWithObjectsAndKeys:
						  [NSString stringWithFormat:@"%f", latitude], @"lat",
						  [NSString stringWithFormat:@"%f", longitude], @"lng",
						  artistList, @"artists",
						  @"tasteSig", @"tasteSig",
						  user, @"email",
						  nil];
	
	[self apiCall:@"checkin.add"
			 args:args
	 successBlock:successBlock
	 failureBlock:failureBlock];
}

- (void) addCheckin {	
	SuccessBlock successBlock = ^(NSString *result) {
		NSLog(@"success block for add check result is %@", result);
	};
	FailureBlock failureBlock = ^(NSString *err) {
		NSLog(@"failure block for add check result is %@", err);
	};
	NSDictionary *args = [[NSDictionary alloc] initWithObjectsAndKeys:
						  @"sean@eye.fi", @"email",
						  @"artisto", @"artists",
						  @"taste", @"tasteSig",
						  @"1", @"lat",
						  @"1", @"lng",
						  nil];
	[self apiCall:@"checkin.add"
			 args:args
	 successBlock:successBlock
	 failureBlock:failureBlock];
}

- (void)loadTrackToPlayForLatitude:(float)latitude longitude:(float)longitude range:(int)range authToken:(NSString *)rdioAuthToken user:(NSString *)user
{
	QueryBlock successBlock = ^(id result) {
		NSLog(@"result i got back is %@", result);
		[mainViewController performSelectorOnMainThread:@selector(playTrack:) 
											 withObject:result
										  waitUntilDone:NO];
	};
	FailureBlock failureBlock = ^(NSString *err) {
		NSLog(@"error i got back is %@", err);

	};
	
	NSDictionary *args = [[NSDictionary alloc] initWithObjectsAndKeys:
						  [NSString stringWithFormat:@"%f", latitude], @"lat",
						  [NSString stringWithFormat:@"%f", longitude], @"lng",
						  [NSString stringWithFormat:@"%d", range], @"radius",
						  rdioAuthToken, @"rdio_auth",
						  user, @"email",
						  nil];
	
	[self apiCall:@"query"
			 args:args
	   queryBlock:successBlock
	 failureBlock:failureBlock];
}	

- (void) query {	
	SuccessBlock successBlock = ^(NSString *result) {
		
	};
	FailureBlock failureBlock = ^(NSString *err) {
		
	};
	NSDictionary *args = [[NSDictionary alloc] initWithObjectsAndKeys:
						  @"email", @"email",
						  @"lat", @"lat",
						  @"lng", @"lng",
						  @"radius", @"radius",
						  nil];
	[self apiCall:@"query"
			 args:args
	 successBlock:successBlock
	 failureBlock:failureBlock];
}

- (void) apiCall:(NSString*)method
			args:(NSDictionary*)args
	  queryBlock:(QueryBlock)successBlock
	failureBlock:(FailureBlock)failureBlock {
	
	{
		dispatch_block_t block;
		block = ^{
			[args retain];
			
			NSURL *reqUrl = [self createUrlWithMethod:method
												 args:args];
			NSLog(@"method is %@, args are %@", method, args);
			NSLog(@"url is %@", [reqUrl description]);
			
			ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:reqUrl];
			
			[request startSynchronous];
			
			NSError *error = [request error];
			if (!error) {
				successBlock([request responseString]);
			} else {
				failureBlock([request responseString]);
			}
		};
		// execute request in dispatch queue
		dispatch_async(queue, block);
	}
	
	
}
	

- (void) apiCall:(NSString*)method
			args:(NSDictionary*)args
	successBlock:(SuccessBlock)successBlock
	failureBlock:(FailureBlock)failureBlock {
	{
		dispatch_block_t block;
		block = ^{
			[args retain];
			
			NSURL *reqUrl = [self createUrlWithMethod:method
												 args:args];
			NSLog(@"method is %@, args are %@", method, args);
			NSLog(@"url is %@", [reqUrl description]);

			ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:reqUrl];

			[request startSynchronous];

				NSError *error = [request error];
				if (!error) {
					successBlock([request responseString]);
				} else {
					failureBlock([request responseString]);
				}
		};
		// execute request in dispatch queue
		dispatch_async(queue, block);
	}
}

- (NSURL*) createUrlWithMethod:(NSString*)method
						  args:(NSDictionary*)args
{	
	// get base url string
	NSMutableString *reqUrl = [NSMutableString stringWithFormat:@"http://blockprtyapp.appspot.com/%@?", method];
	
	// add url-encoded arguments
	for (id key in args) {
		[reqUrl appendString:[NSString stringWithFormat:@"&%@=%@", key, [blockprtyAppDelegate urlEncodeString:(NSMutableString*)[args valueForKey:key]]]];
	}
		
	// make request
	return [NSURL URLWithString:reqUrl];
}

// URL encoding code borrowed from
// http://stackoverflow.com/questions/705448/iphone-sdk-problem-with-ampersand-in-the-url-string
+(NSString*) urlEncodeString:(NSMutableString *)urlStr
{
	NSMutableString *escaped = [[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] mutableCopy];
	NSRange wholeString = NSMakeRange(0, [escaped length]);
	[escaped replaceOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"," withString:@"%2C" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@";" withString:@"%3B" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"=" withString:@"%3D" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"?" withString:@"%3F" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"@" withString:@"%40" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"\t" withString:@"%09" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"#" withString:@"%23" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"<" withString:@"%3C" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@">" withString:@"%3E" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:wholeString];
	[escaped replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:wholeString];
	return [escaped autorelease];
}

- (void)dealloc {
    [window release];
    [super dealloc];
}


@end
